package com.fau.template.dao.impl;

import java.io.Serializable;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.*;
import org.springframework.stereotype.Repository;
import com.fau.template.dao.IBaseDao;
import com.fau.template.util.Page;

@Repository
public class BaseDaoImpl implements IBaseDao {
	
	@Resource(name = "sessionFactory")
	private SessionFactory sessionFactory;
	private boolean cacheQuery = false;
	
	
	public Session getSession() throws HibernateException { 
		Session session = sessionFactory.getCurrentSession();
		session.setFlushMode(FlushMode.COMMIT);
		return session;
    }

	@Override
	public void flush() {
		if (getSession().isOpen()) {
			getSession().flush();
		}
	}

	@Override
	public Object getObject(Class<?> c, Serializable id) {
		return getSession().get(c, id);
	}
	
	@Override
	public Object getObjectByHql(String hql, Object... value) {
		Query q = getSession().createQuery(hql);
		if(isCacheQuery()) {
			q.setCacheable(true);
		}

		if (hql.contains("?")) {
			for(int i = 0;i < value.length;i++) {
				q.setParameter(i, value[i]);
			}
		}

		return q.uniqueResult();
	}

	@Override
	public void updateObject(Object o) {
		getSession().update(o);
	}

	@Override
	public void insertObject(Object o) {
		getSession().save(o);
	}

	@Override
	public boolean updateByHql(String hql, Object... value) {
		Query q = getSession().createQuery(hql);
		if (hql.contains("?")) {
    		for(int i = 0;i < value.length;i++) {
    			q.setParameter(i, value[i]);
    		}
    	}
		int flag = q.executeUpdate();
		return flag != 0;
	}

	@Override
	public boolean updateBySql(String sql, Object... value) {
		Query q = getSession().createSQLQuery(sql);
		if (sql.contains("?")) {
			for(int i=0;i<value.length;i++) {
    			q.setParameter(i, value[i]);
    		}
		}
		int flag = q.executeUpdate();
		return flag != 0;
	}

	@Override
	public void deleteObject(Object o) {
		getSession().delete(o);
	}
	
	@Override
	public List<?> getListByHql(String hql, Integer rows, Object... value) {
		Query q = getSession().createQuery(hql);

		if(isCacheQuery()) {
			q.setCacheable(true);
		}

		if(rows != null) {
			q.setMaxResults(rows);
		}

    	if (hql.contains("?")) {
    		for(int i = 0;i < value.length;i++) {
    			q.setParameter(i, value[i]);
    		}
    	}

		// Return the query results as a List. If the query contains multiple results per row, the results are returned in an instance of Object[].
		List<?> l = q.list();
    	return l;
	}
	
	@Override
	public int getIntCount(String hql,Object ... value) {
		Query q = getSession().createQuery(hql);

		if (hql.contains("?")) {
    		for(int i=0;i<value.length;i++) {
    			q.setParameter(i, value[i]);
    		}
    	}

		Object o = q.uniqueResult();
		return new Integer(String.valueOf(o));
	}
	
	@Override
	public Page getPage(int currentPage, int numPerPage, String statusSql, String countHql, List<Object> objectList) {
    	Page page = new Page();
		page.setPageSize(numPerPage);// 每页大小
    	page.setCurPage(currentPage);// 当前页

		int totalRow = getIntCount(countHql, objectList.toArray());
    	page.setTotalRow(totalRow);// 总行数

    	int totalPage = (int) Math.ceil((double)totalRow / numPerPage);
    	page.setTotalPage(totalPage);// 总页数
    	
    	if(currentPage > totalPage) {
    		currentPage = totalPage;
    	}
    	
    	page.setBeginIndex((currentPage - 1) * numPerPage);// 分页开始索引
    	
		Query q = getSession().createQuery(statusSql);
		if(isCacheQuery()) {
			q.setCacheable(true);
		}
		if (statusSql.contains("?")) {
			for(int i = 0;i<objectList.size();i++) {
				q.setParameter(i, objectList.get(i));
			}
		}
		q.setFirstResult(page.getBeginIndex());
		q.setMaxResults(page.getPageSize());

		List<?> list = q.list();
		page.setResult(list);
    	return page;
    }
	
	public boolean isCacheQuery() {
		return cacheQuery;
	}

	@Override
	public BaseDaoImpl setCacheQuery(boolean cacheQuery) {
		this.cacheQuery = cacheQuery;
		return this;
	}

}
